Débito OTP
Esta sección describe el proceso para generar una operación de cobro utilizando una clave de un solo uso (OTP). La transacción consiste en solicitar un cobro que se valida con una clave pregenerada y proporcionada previamente al usuario pagador, lo que garantiza un proceso seguro y eficiente.
Para realizar un cobro exitoso ejecuta los siguientes pasos:
1. Genera una solicitud OTP para el cliente.
2. Solicita la clave al cliente pagador para colocarla en el modelo de transacción.
3. Envía la operación al endpoint especificado y espera por la respuesta.
Flujo de una transacción de débito con OTP (Producto 050 (Débito) - SubProducto 002 (con clave OTP)
1. Realizar un request al endpoint de solicitud OTP /api/v1/request/otp.
2. El banco pagador envía la clave OTP a su cliente para autorizar el débito por la vía predeterminada, bien sea SMS, Push o Email.
3. Realizar un request al endpoint de débito OTP /api/v1/transaction/otp para iniciar la transacción, con los mismos datos del request de solicitud OTP del paso 1, agregando la OTP suministrada por el cliente en el campo OTP de receiving_user. Importante indicar el URL de notificación Webhook donde recibirán la respuesta definitiva de la transacción.
4. Recibir en el Webhook de notificación el estatus de la transacción. El mensaje recibido tiene un campo con el mensaje firmado para validar la autenticidad del mismo, para mayor detalle ver la documentación de Proceso de Firma para Notificaciones.
POST api/v1/transaction/otp
{
"internal_id": "3A6861CB5DB5",
"group_id": "F26D8D165DC4",
"account": {
"bank_code": "0001",
"type": "CNTA",
"number": "00011234567890123456"
},
"amount": {
"amt": 5,
"currency": "VES"
},
"concept": "Cobro de servicios",
"notification_urls": {
"web_hook_endpoint": "https://www.pruebas.sypago.com/notification"
},
"receiving_user": {
"name": "John Doe",
"otp": "12345678",
"document_info": {
"type": "V",
"number": "123456789"
},
"account": {
"bank_code": "0102",
"type": "CELE",
"number": "04140121877"
}
}
}
{
"transaction_id": "AFD1AD8DA41E",
"operation_secret": "66471d35-6252-47aa-a99f-2b4873dc5adc"
}"
Cargando datos...
Para consultar si una transacción se encuentra "En proceso" o "Pendiente", utilice el siguiente endpoint. Solo debe incluir el ID de la transacción como parámetro para obtener el estado de la operación.
GET api/v1/transaction/{id}
- C#
- Java
class CobroxOTP
{
static String BASE_URL = "https://pruebas.api.sypago.net";
static String TOKEN_PATH = "/api/v1/auth/token";
static String DEBITO_PATH = "/api/v1/transaction/otp";
static String CTA = "00015678901234567890";
static SocketsHttpHandler shHandler;
static async Task Main(string[] args)
{
shHandler = new SocketsHttpHandler
{
MaxConnectionsPerServer = 100,
PooledConnectionLifetime = TimeSpan.FromMinutes(10),
ConnectTimeout = TimeSpan.FromSeconds(200),
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(5),
ResponseDrainTimeout = TimeSpan.FromSeconds(5),
};
HttpClient? cliente;
cliente = new HttpClient(shHandler);
cliente.BaseAddress = new Uri(BASE_URL);
string body = "{"client_id":"user_name","secret":"api_key"}";
var contenido = new StringContent(body, Encoding.UTF8, "application/json");
var respuesta = await cliente.PostAsync(TOKEN_PATH, contenido);
var resultado = await respuesta.Content.ReadAsStringAsync();
JsonDocument jsonDoc = JsonDocument.Parse(resultado);
string accessToken = jsonDoc.RootElement.GetProperty("access_token").GetString();
//Console.WriteLine(accessToken);
var internal_id = new Random().Next(1, 999999).ToString("000000") + new Random().Next(1, 999999).ToString("000000");
var group_id = new Random().Next(1, 999999).ToString("000000") + new Random().Next(1, 999999).ToString("000000");
body = "{"internal_id": "" + internal_id + "","group_id": "" + group_id + "","account": {"bank_code": "0001","type": "CNTA","number": "" + CTA + ""},"amount": {"amt": 2.00,"currency": "VES"},"concept": "PruebaCiclo100-SOAPUI","notification_urls": {"web_hook_endpoint": "http://Urlretorno:8080/transaction/sts"},"receiving_user": {"name": "Ruben Puña","otp": "123456","document_info": {"type": "V","number": "12345678"},"account": {"bank_code": "0102","type": "CELE","number": "4121234567"}}}";
cliente.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
contenido = new StringContent(body, Encoding.UTF8, "application/json");
respuesta = await cliente.PostAsync(DEBITO_PATH, contenido);
resultado = await respuesta.Content.ReadAsStringAsync();
Console.WriteLine($"resultado: {resultado}");
Console.WriteLine("
");
jsonDoc = JsonDocument.Parse(resultado);
string transaction_id = jsonDoc.RootElement.GetProperty("transaction_id").GetString();
Console.WriteLine($"transaction_id: {transaction_id}");
}
}
public class CobroxOTP {
static String BASE_URL = "https://pruebas.api.sypago.net";
static String DEBITO_OTP_PATH = "/api/v1/transaction/otp";
static String cuenta = "00015678901234567890";
static String TOKEN_PATH = "/api/v1/auth/token";
static String CREDEN = """
{
"client_id":"user_name",
"secret":"api_key"
}
""";
// Cliente Http
public static final MediaType JSON = MediaType.get("application/json");
OkHttpClient client = new OkHttpClient();
public static void main(String[] args) throws IOException {
CobroxOTP sypago = new CobroxOTP();
String internal_id = RandomStringUtils.random(12, true, true);
String group_id = RandomStringUtils.random(12, true, true);
String IP = java.net.InetAddress.getLocalHost().getHostAddress();
String body = """
{
"internal_id": "%s",
"group_id": "%s",
"account": {
"bank_code": "0001",
"type": "CNTA",
"number": "%s"
},
"amount": {
"amt": 2.00,
"currency": "VES"
},
"concept": "PruebaCiclo100-SOAPUI",
"notification_urls": {
"web_hook_endpoint": "http://%s:8080/transaction/sts"
},
"receiving_user": {
"name": "Ruben Puña",
"otp": "123456",
"document_info": {
"type": "V",
"number": "12345678"
},
"account": {
"bank_code": "0102",
"type": "CELE",
"number": "4121234567"
}
}
}
""".formatted(internal_id, group_id, cuenta,IP);
var resp = sypago.debitotOTP(BASE_URL+DEBITO_OTP_PATH, body, sypago.getToken(BASE_URL+TOKEN_PATH, CREDEN));
System.out.println("Identificador de la transacción: " + resp);
}
public String debitotOTP(String url, String json, String token) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer " + token)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
int httpcode = response.code();
if(httpcode == 401) return "No se ha autenticado con el token";
JSONObject respuesta = new JSONObject(response.body().string());
if(httpcode == 409) {
return respuesta.getString("message");
}
return respuesta.getString("transaction_id");
}
}
public String getToken(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
int httpcode = response.code();
if(httpcode == 401) return "No se ha autenticado con el token";
JSONObject respuesta = new JSONObject(response.body().string());
if(httpcode == 409) {
return respuesta.getString("message");
}
return respuesta.getString("access_token");
}
}
}